#-*- coding: utf-8 -*-

#--- PYTHON IMPORTS ---
from os import path
from datetime import date

#--- FRAMEWORK IMPORTS ---
from django.db import models
from django.conf import settings
from django.db.models import signals
from django.core.mail import send_mass_mail
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User, Group

from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from django.template.defaultfilters import slugify

#--- APP IMPORTS ---
from . import app_settings
from . import utils

try: import pyclamav
except: pyclamav = None

__all__=['Forum', 'ForumGroup', 'ForumMessage', 
         'ForumProfile', 'ImageGallery', 'ImageItem', 
         'MessageBox', 'Topic', 'Reply',
         'Poll', 'PollOption', 'PollPick',
         'Rate', 'Visit', 'ReportAbuse', 'AbuseChoice']


class DatedModel(models.Model):
    created_time = models.DateTimeField(_("Created time"), auto_now_add=True)    
    modified_time = models.DateTimeField(_("Modified time"), auto_now=True)
    
    class Meta:
        abstract = True


class ExtendedModel(DatedModel):
    created_by = models.ForeignKey(User, null=True, blank=True, related_name='%(class)s_creator')

    class Meta:
        abstract= True


class AbuseChoice(ExtendedModel):
    'Define uma opção de abuso que pode ser reportada'
    code = models.CharField(primary_key=True, max_length=10)
    text = models.CharField(max_length=40, help_text=_('Text showed to user'))
    
    class Meta:
        db_table = 'forum_abuse_choice'
    
    def __unicode__(self):
        return ugettext(self.text)
    
        
class ReportAbuse(DatedModel):
    'Define um abuso relatado'
    author = models.ForeignKey(User, editable=False, related_name='frm_abuse_report_list')
    topic = models.ForeignKey('Topic', related_name='abuse_report_list')
    reason = models.ForeignKey(AbuseChoice, verbose_name=_('Reason'))
    text = models.TextField(_('Reason'), help_text=_('why are you reporting this topic?'))
    
    class Meta:
        db_table="forum_report_abuse"
        
class Visit(models.Model):
    "Records an user visit to a topic"
    ip = models.IPAddressField() # ip do usuario
    date = models.DateField(auto_now_add=True) # data da visita
    topic = models.ForeignKey("Topic", related_name="visits") # visitou oq?

    class Meta:
        db_table="forum_visit"
        unique_together = [("ip", "date", "topic")]

    def __unicode__(self):
        return _("Visit to '%(post)s at %(date)s'") % {"post":self.post, "date":self.date.strftime(getattr(settings, "DEFAULT_DATE_FORMAT", "%d/%b/%y"))}


class ForumMessage(DatedModel):
    "Message sent from an User to another"
    readen=models.BooleanField(default=False, editable=False)
    box=models.ForeignKey('MessageBox', related_name="messages", editable=False)
    author=models.CharField(_('Who sent this?'), max_length=30) # guarda o username do remetente
    title=models.CharField(_("Message Title"), max_length=60, default=_("Empty title"))
    content=models.TextField(verbose_name=_("Message content"))

    class Meta:
        db_table="forum_user_message"        
        ordering=('-created_time', 'author') # ordena pela mais nova e depois pelo usuário

    def __unicode__(self): return self.title

    def link(self):
        class Link(utils.Link):
            def __repr__(self):
                return reverse('forum-user-message_box', args=[self.id])
            def remove(self):
                return reverse('forum-user-message_box-del', args=[self.id])
            def msg_author(self):
                return reverse('forum-user-profile', args=[self.author])
            def reply(self):
                return reverse('forum-send_pvt', args=[self.author])            
        return Link(self)

    # aliases
    get_absolute_url = link

def send_message(from_user, to, title, message):
    ForumMessage.objects.create(
        system_message=True,
        from_user=from_user,
        to=to,
        title=title,
        content=message
    )


# --- OK ---
class MessageBox(DatedModel):
    "It's a mailbox...for messages!"
    profile = models.OneToOneField('ForumProfile', related_name="message_box")
    limit = models.IntegerField(default=app_settings.MSG_BOX_DEFAULT_SIZE, help_text=_("Messages limit")) # quantas mensagens por usuário?
    away = models.BooleanField(_("Away?"), default=False)
    away_message = models.TextField(default=_("I'm not here"), blank=True)
    blocked_users = models.ManyToManyField('ForumProfile', related_name="blocking_users")

    class Meta:
        db_table="forum_user_messagebox"
    
    def is_full(self):
        return self.messages.count()>=self.limit


class ImageGallery(ExtendedModel):
    "An user can have a image gallery, where he places images he want to share."
    owner = models.ForeignKey("ForumProfile",
        related_name="galleries", editable=False)
    slug = models.SlugField(max_length=60)
    name = models.CharField(_("Identify your gallery with a name"), max_length=60)
    limit = models.PositiveIntegerField(_("Maximum number of images per gallery"), default=10)
    description = models.TextField(_("Gallery description"))
    
    def __unicode__(self):
        return self.name

    class Meta:
        db_table="forum_image_gallery"


# --- OK ---
class ImageItem(DatedModel):
    "A image in the image galley"
    gallery = models.ForeignKey(ImageGallery, related_name="images", editable=False)
    image = models.ImageField(upload_to=path.join("forum", "users", "gallery"), verbose_name=_("Gallery Image"))
    description = models.TextField(_("What's this image about?"))

    class Meta:
        db_table="forum_image_item"
        
    def __unicode__(self):
        return self.image.url
    
    def link(self):
        class Link(utils.Link):
            def __repr__(self):
                return reverse('forum-user-image_gallery-item', args=(self.gallery, self.id))
        return Link(self)


class ForumProfile(DatedModel):
    "User forum info goes here"
    user = models.OneToOneField(User, related_name="frm_profile")
    title = models.CharField(_("User title"),
        max_length=20, default=_("Regular user"), blank=True,
        help_text=_("Defines user title based on dump forum statistics"))
    pvt_only_from_friends = models.BooleanField(_("If marked, only friends may send you messages."),
        help_text=_("Mark this if you're getting too many unwelcomed messages."),
        blank=True, default=False)
    image = models.ImageField(_("Your profile image"),
        upload_to="forum/users/avatar/", null=True,
        default=None, blank=True,
        help_text=_("Your display image"))
    signature = models.TextField(_("Your Signature"),
        blank=True, null=True,
        help_text=_("Accepts 'safe' html markup"))
    friends = models.ManyToManyField("ForumProfile")
    
    topic_count = models.IntegerField(default=0) # contador de topicos do usuario
    reply_count = models.IntegerField(default=0) # contador de respostas do usuario
    friends_count = models.IntegerField(default=0)
    
    class Meta:
        db_table="forum_user_profile"

    def __unicode__(self):
        return self.user.username

    def link(self):
        class Link(utils.Link):
            def __repr__(self):
                return reverse('forum-user-profile', args=[self.username])
            def edit(self):
                return reverse('forum-user-profile-edit')
            def send_pvt(self):
                return reverse('forum-send_pvt', args=[self.username])
            def msg_box(self):
                return reverse('forum-user-message_box')
            def image_gallery(self):
                return reverse('forum-user-gallery', args=[self.username])
            def friends(self):
                return reverse('forum-user-friends')
            def add_friend(self):
                return reverse('forum-user-friends-add', args=[self.username])
            def remove_friend(self):
                return reverse('forum-user-friends-remove', args=[self.username])
            def all_topics(self):
                return reverse('forum-user-all_topics', args=[self.username])
            
        return Link(self)

    def avatar_url(self):
        "Returns the user image url"
        if self.image: return self.image.url
        # default avatar image
        else: return path.join(settings.MEDIA_URL, "images/forum/django_avatar.png")
    
    def update_reply_counter(self):
        user = self.user
        self.reply_count = user.forum_reply_list.active().count()
        self.save()
        
    def update_topic_counter(self):
        user = self.user
        self.topic_count = user.forum_topic_list.active().count()
        self.save()

    def post_stat(self):
        "User's post statistics"
        query = Reply.objects.active()
        post_count = query.count()
        user_posts = query.filter(author=self.user).count()

        if post_count==0:
            return _("0 Replies - 100% of 0")

        return self._stats(user_posts, post_count, "Posts")

    def topic_stat(self):
        "Returns user topic statistics, like usage"
        query = Topic.objects.active()
        post_count = query.count()
        user_posts = query.filter(author=self.user).count()

        if post_count==0:
            return _("0 Topics - 100% of 0")

        return self._stats(user_posts, post_count, "Topics")
    
    def update_friends_counter(self):
        self.friends_count=self.friends.count()
        self.save()
    
    def add_friend(self, friend):
        self.friends.add(friend)
        self.update_friends_counter()

    def remove_friend(self, friend):
        self.friends.remove(friend)
        self.update_friends_counter()

    def _get_friends(self):
        if len(self.friends)>0:
            return self.friends.split(',')
        else: return []

    def _set_friends(self, friends):
        if len(friends)>0:
            self.friends=','.join(friends)
        else: self.friends=''

    def _get_username(self):
        return self.user.username

    def _get_messages(self):
        return ForumMessage.objects.filter(to=self.user.username)

    # aliases
    get_absolute_url = link
    username = property(_get_username)
    forum_messages = property(_get_messages)
    friends_list = property(_get_friends, _set_friends)


class ForumGroup(ExtendedModel):
    "Forum group sorts foruns in the main page"
    name = models.CharField(max_length=60, unique=True,
            verbose_name=_("This will be used to sort foruns in the main page"),
            help_text=_("ONLY foruns that have a group will appear in the main page"))

    class Meta:
        db_table = "forum_group"
        ordering = ['name']
    
    def __unicode__(self):
        return self.name
    
    def link(self):
        class Link(utils.Link):
            def __repr__(self):
                return reverse('forum-index')
        return Link(self)
    get_absolute_url = link


class Forum(ExtendedModel):
    """This is a forum or subforum for the website"""
    active = models.BooleanField(_("Is active?"), default=True, help_text=_("Unselect to hide from users."))

    #-- data ---#
    group = models.ForeignKey("ForumGroup",
        verbose_name=_("Group"), help_text=_("Foruns within the same group are showed together"),        
        related_name="forum_list", null=True, blank=True)
    parent = models.ForeignKey("Forum",
        verbose_name=_('Parent forum'), help_text=_("If this is a subforum, define the forum above it, here"),
        related_name="subforuns", null=True, blank=True)

    title = models.CharField(_('Forum name'), max_length=40)
    slug = models.SlugField(max_length=40)
    short = models.CharField(_('Short description of forum subject'), max_length=60, blank=True, null=True)
    
    image = models.ImageField(upload_to=path.join("forum", "images", "head"),
        verbose_name=_('Define this image if you would like to have a header image'),
        help_text=_("Something with +- 950px of width for 200px of height"),
        null=True, blank=True)
    image_small = models.ImageField(upload_to=path.join("forum", "images", "small"),
        verbose_name=_("Image showed beside the forum's name"),
        help_text=_("If not set, a default image will handle the job"),
        null=True, blank=True)    
    moderation = models.ManyToManyField(User, related_name='has_moderation',
        verbose_name=_("Moderation"), help_text=_("People allowed to moderate this forum"),
        null=True, blank=True)
    
    # -- cfg ---
    post_notify = models.BooleanField(default=False, verbose_name=_("Notify moderation by email on new topics?"))    
    allow_topics = models.BooleanField(default=True, verbose_name=_("Allow topics?"))
    allow_reply_edit = models.BooleanField(default=True, verbose_name=_("Allow user to edit his replies?"))
    allow_reply_del = models.BooleanField(default=True, verbose_name=_("Allow user to remove his replies?"))    
    allow_view_only_to_logged_users = models.BooleanField(default=False, verbose_name=_("Block non-logged users from viewing content?"))
    #allow_rating = models.BooleanField(default=False, verbose_name=_("Can users rate replies?"))
    #allow_polls = models.BooleanField(default=True, verbose_name=_("Allow polls?"))
    #hide_new_messages = models.BooleanField(default=False, verbose_name=_("Hide new messages until approval?"))
    
    # -- Updated by signals --    
    topic_count = models.IntegerField(default=0, editable=False)
    reply_count = models.IntegerField(default=0, editable=False)

    class Meta:
        db_table="forum"
        ordering = ['active', 'title']

    def __unicode__(self):
        return self.title
    
    def get_parent_tree(self):
        # retorna uma lista com os foruns ascendentes
        tree = [self]
        temp = self        
        while temp.parent:
            temp=temp.parent
            tree.append(temp)
        tree.reverse()
        return tree
    
    def get_latest_topic(self):
        try: return self.topic_list.active().latest()
        except: return None

    def get_forum_image(self):
        "Retorna a imagem do forum ou do forum ascendente mais proximo"
        if self.image: return self.image.url
        elif self.parent is not None: return self.parent.get_forum_image()
        else: return None
    
    def update_topic_counter(self):
        'Atualiza o contador de topicos'
        self.topic_count=self.topic_list.active().count()
        self.save()
    
    def update_reply_counter(self):
        self.reply_count=self.topic_list.active().aggregate(models.Sum('reply_count'))['reply_count__sum']
        self.save()

    def formated(self):
        "Returns this forum name with one '-' for each parent forum of this forum"
        return '-'*self.level+self.title

    def link(self):
        class Link(utils.Link):
            def __repr__(self):
                return reverse("forum-expose", args=[self.id, self.slug])
            def post(self):
                return reverse("forum-post", args=[self.id, self.slug])
        return Link(self)

    # alias
    get_absolute_url = link
    parent_tree = property(get_parent_tree)
    latest_topic = property(get_latest_topic)


class Poll(DatedModel):
    question = models.CharField(max_length=80)

    class Meta:
        db_table="forum_poll"
        ordering=["-created_time"]

    def __unicode__(self):
        return _("poll: %s") % self.question

    def count(self):
        "Returns how many answers has this poll"
        return PollOption.objets.filter(poll=self).count()

    def who(self):
        "Returns a list with who answerd this poll"
        return PollPick.objets.filter(poll=self).values("user")


class PollOption(models.Model):
    poll = models.ForeignKey("Poll", related_name="options")
    option = models.CharField(_("Option text"), max_length=60)
    image = models.ImageField(_("Option image"), upload_to=path.join("forum", "poll", "images"), blank=True, null=True)

    class Meta:
        db_table="forum_poll_option"

    def __unicode__(self): 
        return self.option
    
    def who(self):
        "returns a list with who picked this option"
        return PollPick.objects.filter(option=self).values("user")


class PollPick(DatedModel):
    "Someone's choice for this poll"
    # tells who picked the poll option
    user = models.ForeignKey(User, related_name="forum_pollpick")
    # tells which is the poll
    poll = models.ForeignKey("Poll", related_name="picked")
    # tells which options was picked
    option = models.ForeignKey("PollOption", related_name="picked")

    class Meta:
        db_table="forum_pollpick"


class Rate(DatedModel):
    user = models.ForeignKey(User, related_name="forum_rating_list")
    reply = models.ForeignKey("Reply", related_name="rating_list")
    
    class Meta:
        db_table="forum_rate"
        unique_together=[('reply', 'user')]

        
class View(models.Model):
    'Grava visitas de usuários a um tópico'
    created_date = models.DateField()
    user = models.ForeignKey(User, related_name="forum_viewed_topics", null=True, blank=True)
    topic = models.ForeignKey('Topic', related_name='view_list')
    address = models.IPAddressField()
    
    class Meta:
        db_table = 'forum_topic_view'
    
    def __unicode__(self):
        return _(u'Visit of %(user)s to topic "%(topic)s" at "%(date)s"') % {"user":self.user,
            "topic":self.topic, "date":self.created_date.strftime("%d %B, %Y")}

    def link(self):
        return self.topic.link()
    
    # alias
    get_absolute_url = link


class TopicManager(models.Manager):
    def active(self):
        # retorna apenas os topicos ativos
        return self.filter(active=True)
    

class Topic(DatedModel):
    """Representa um tópico de um fórum. Tópicos são entidades que armazenam informações
    extras, como enquetes, imagens, etc. O tópico não armazena texto inicial, sendo esse
    obtido a partir da primeira postagem.
    
    author - who made the topic
    active - use this instead of removing it
    closed - users can not modify topic anymore
    fixed  - will always be showed before 'normal' topics
    attach - adds file to topic
    attach_warning - tell if attachment looks suspicious
    """
    
    forum = models.ForeignKey(Forum, related_name="topic_list", verbose_name=_("Related forum"))
    author = models.ForeignKey(User, related_name="forum_topic_list")
    keywords = models.CharField(_("Keywords"), max_length=40, blank=True, null=True, 
        editable=False, help_text=_("Used by HCS"))
    active = models.BooleanField(_("Is active?"), default=True, help_text=_("Unmark to hide from users."))
    closed = models.BooleanField(_("Is closed?"), default=False, help_text=_("Select to block further modification."))
    fixed = models.BooleanField(_("Make it fixed?"), default=False, help_text=_("Select to always show it on top."))
    title = models.CharField(_("Title"), max_length=40, blank=False) # same as of first reply
    slug = models.SlugField(max_length=40)
    short = models.CharField(_("Subtitle"), max_length=60, blank=True,
        default="", help_text=_("Optional short description"))
    poll = models.OneToOneField(Poll, default=None, null=True)
    image = models.ImageField(_("Topic image"), upload_to="forum/images/topic/",
        null=True, blank=True, default=None, help_text=_("Showed at top."))    
    attach = models.FileField(_("Attached file"),
        upload_to="forum/files/attach/", null=True, blank=True, default=None,
        help_text=_("Used to share small non-binary files."))
    attach_warning = models.BooleanField(_('Does the attached file seems dangerous?'),
        default=False, editable=False)
    
    # contador de visitas e respostas
    views_count = models.IntegerField(default=0, editable=False)
    reply_count = models.IntegerField(default=0, editable=False)
    
    objects = TopicManager()
    
    class Meta:
        db_table="forum_topic"
        get_latest_by='created_time'
        ordering=["-fixed", "-created_time", "title"]
    
    def __unicode__(self):
        return self.title
        
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug=slugify(self.title)
        super(Topic, self).save(*args, **kwargs)
    
    def html_id(self):
        return "topic_%d" % hash("%d%s" % (self.id, self.title))
        
    def get_status_image(self):
        if not self.active:
            return path.join(settings.MEDIA_URL, "images/forum/deny.png")
        if self.fixed:
            return path.join(settings.MEDIA_URL, "images/forum/text_fixed.png")
        if self.closed:
            return path.join(settings.MEDIA_URL, "images/forum/padlock.png")
        return path.join(settings.MEDIA_URL, "images/forum/text_block.png")
    
    def get_username(self):
        'atalho para o username do author do topico'
        return self.author.username
    
    def update_reply_counter(self):
        'Atualiza o contador de respostas'
        self.reply_count=self.reply_list.active().count()
        self.save()
    
    def update_views(self, request):
        'Atualiza o contador de visualizações'
        address = request.META["REMOTE_ADDR"]
        
        obj, status = View.objects.get_or_create(created_date=date.today(),
            user=request.user.is_authenticated() and request.user or None,
            topic=self, address=address)

        if status:
            self.views_count=self.view_list.count()
            self.save()

    def get_latest_reply(self):
        try:
            return self.reply_list.active().latest()
        except: return None
    
    def link(self):
        class Link(utils.Link):
            def __repr__(self):
                return reverse("forum-topic", args=[self.id, self.slug])
            def reply(self):
                return reverse("forum-reply", args=[self.id, self.slug])
            def report_abuse(self):
                return reverse("forum-report_abuse", args=[self.id, self.slug])
            def follow(self):
                return reverse('forum-follow', args=(self.id, self.slug))
            def unfollow(self):
                return reverse('forum-unfollow', args=(self.id, self.slug))
            def moderate(self):
                return reverse('forum-moderate', args=(self.id, self.slug))
        return Link(self)
    
    username = property(get_username)
    status_img = property(get_status_image)
    latest_reply = property(get_latest_reply)
    get_absolute_url = link


class ReplyManager(models.Manager):
    def active(self):
        return self.filter(active=True)
    

class Reply(DatedModel):
    """Representa a respota de um usuário a um tópico"""
    
    topic = models.ForeignKey(Topic, related_name="reply_list", verbose_name=_("Related topic"))
    author = models.ForeignKey(User, related_name="forum_reply_list")
    active = models.BooleanField(_("Is active?"), default=True, help_text=_("Unselect to hide from users."))
    edited = models.BooleanField(_("Was edited?"), default=False, blank=True, help_text=_("Data was edited after creation?"))
    
    title = models.CharField(_("Subject"), max_length=40, help_text=_("What are you talking about?"))
    short = models.CharField(_("Subtitle"), max_length=60, blank=True,
        default="", help_text=_("Optional short description"))
    text = models.TextField(_("Text"), blank=False) # response text
    
    objects = ReplyManager()
    
    class Meta:
        db_table = "forum_reply"
        get_latest_by = "created_time"
        ordering = ["active", 'created_time', 'title']

    def __unicode__(self):
        return self.title
    
    def _get_username(self):
        return self.author.username
    
    def html_id(self):
        return "reply_%d" % hash("%d%s" % (self.id, self.title))
    
    def link(self):
        class Link(utils.Link):
            def __repr__(self):
                return reverse("forum-topic", 
                    args=[self.topic.id, self.id])+'?page=%d#%s' % (index(self, self.topic.reply_list.active(), app_settings.SMALL_LIST), self.html_id())
            def edit(self):
                return reverse("forum-reply-edit", args=(self.id,))
            def remove(self):
                return reverse("forum-reply-del", args=(self.id,))
        return Link(self)
        
    # aliases
    get_absolute_url = link
    username = property(_get_username)

class Follow(DatedModel):
    "Guarda uma informação de acompanhamento de tópico"
    active = models.BooleanField(default=False, blank=True)
    topic = models.ForeignKey('Topic', related_name="follow_list")
    frm_profile = models.ForeignKey(ForumProfile, related_name="follow_list")

    class Meta:
        db_table = 'forum_follow'
        unique_together = (('topic', 'frm_profile'),)
    
def hcs(sender, instance, *args, **kwargs):
    """Human cognitive system
    Permite fazer buscas baseadas em um algoritmo 'achista',
    semelhante à forma como os humanos fazem inferência.
    
    Arguments:
    sender - Reply
    """

    keywords = [key for key in instance.title.lower().split() if len(key)>2]
    keywords = [key for key in keywords if key in instance.text.lower().split()]
    keywords = set(keywords)

    if len(keywords):
        # o HCS considera as palavras que aparecem
        # no titulo e no texto como as mais importantes para a busca
        instance.keywords = ' '.join(keywords)

def index(o, l, s):
    """Informa em qual pagina de uma queryset esta um objeto"""
    for i in range(len(l)):
        if l[i]==o:
            return (i/s)+1    

def update_reply_counters(sender, instance, *args, **kwargs):
    '''Sender - Reply'''
    instance.topic.update_reply_counter()
    instance.topic.forum.update_reply_counter()
    instance.author.frm_profile.update_reply_counter()

def update_topic_counters(sender, instance, *args, **kwargs):
    '''Sender - Topic'''
    instance.forum.update_topic_counter()
    instance.author.frm_profile.update_topic_counter()

def user_post_save(sender, instance, created, *args, **kwargs):
    'Cria um forum_profile para os usuarios'
    if created:
        instance.forum_profile = ForumProfile.objects.create(user=instance)

def profile_post_save(sender, instance, created, *args, **kwargs):
    """Cria a caixa de mensagens do usuário
    Arguments:
    sender - User
    """
    if created: 
        MessageBox.objects.create(profile=instance)
        
def scan_for_viruses(sender, instance, created, *args, **kwargs):
    'Procura por vírus no arquivo anexo de um forum usando o pyclamav, se disponivel'
    if created and instance.attach is not None:
        if pyclamav is None: 
            print _("Pyclamav not found in system. Virus scanning canceled.")
        else:
            result = pyclamav.scanfile(instance.attach.path)
            if result[0]>0:
                print _("Attach infected with %(virus)s.") % result[1]
                instance.attach_warn=True
                instance.save()

def notify_on_post(sender, instance, created, *args, **kwargs):
    """Notifica os moderadores caso um novo tópico seja criado.

    sender - Topic"""
    forum = instance.forum

    if created and forum.post_notify:
        mod_list = instance.moderation.filter(is_active=True)
        email_message = [
            ugettext("Reporting new topic for '%s'" % instance), # assunto
            ugettext("""You're receiving this message because '%(ins)s' configuration requires so. 
The new topic can be viewed here: <br /> %(link)s""") % {"ins":instance, "link":instance.link()}, # corpo
            app_settings.FORUM_EMAIL,
            [user.email for user in mod_list]
        ]

        try:
            send_mass_mail(email_message,
                           auth_user=app_settings.EMAIL_HOST_USER,
                           auth_password=app_settings.EMAIL_HOST_PASSWORD)
        except Exception, e:
            print e
            print ugettext("There's a error with your email configuration")

def notify_on_reply(sender, instance, created, *args, **kwargs):
    """Avisa por email todos os usuários que acompanham o tópico de que ele recebeu
    uma nova resposta

    sender - Reply"""
    topic = instance.topic
    forum = topic.forum

    if created:
        if forum.post_notify:
            moderation = forum.moderation.filter(is_active=True)
            email_message = [
                ugettext("Topic '%(topic)s' received a new reply") % {"topic":topic}, # subject
                ugettext("""You're receiving this message because '%(forum)s' configuration requires so.
The topic for the reply can be viewed here: <br /> %(link)s""") % {"forum":forum, "link":topic.link()},
                app_settings.FORUM_EMAIL,
                [user.email for user in moderation]
            ]

            try:
                send_mass_mail(email_message,
                               auth_user=app_settings.EMAIL_HOST_USER,
                               auth_password=app_settings.EMAIL_HOST_PASSWORD)
            except:
                print ugettext("There's a error with your email configuration")    
    
# connecting stuff up
#signals.pre_save.connect(hcs, Reply, dispatch_uid="forum_hcs_system")

signals.post_save.connect(user_post_save, User, dispatch_uid="frmbr_user_post_save")
signals.post_save.connect(profile_post_save, ForumProfile, dispatch_uid="frmbr_profile_post_save")
signals.post_save.connect(update_reply_counters, Reply, dispatch_uid="frmbr_update_reply_counters")
signals.post_save.connect(update_topic_counters, Topic, dispatch_uid="frmbr_update_topic_counters")
signals.post_save.connect(notify_on_reply, Reply, dispatch_uid="frmbr_notify_on_reply")
signals.post_save.connect(notify_on_post, Topic, dispatch_uid="frmbr_notify_on_post")

# habilitar checagem por vírus?
if app_settings.CHECK_ATTACH_FOR_VIRUS: 
    signals.post_save.connect( scan_for_viruses, sender=Topic, dispatch_uid="forum_scan_attach_for_viruses")
